﻿using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;

namespace FolderSynchronizer
{
	/// <summary>
	/// Класс, в котором реализуется метод этапа копирования в промежуточную папку.
	/// </summary>
	internal class TempStager
	{
		private readonly ISynchronizer copier;
		private readonly SynchronizersUtility preCopier;
		private readonly DriveInfo targetDriveInfo;
	    private readonly DriveInfo tempDriverInfo;
		private readonly List<FileInfo> filesForCopy;

		/// <summary>
		/// Конструктор
		/// </summary>
		/// <param name="copier">Объект, осуществляющий копирование, типа Synchronizer.</param>
		public TempStager(ISynchronizer copier)
		{
			this.copier = copier;
		    preCopier = new SynchronizersUtility(copier.SourceFolder, copier.PathToTempFolder, copier.Settings, true, false, true, true, true);
			targetDriveInfo = new DriveInfo(copier.TargetFolder);
		    tempDriverInfo = new DriveInfo(copier.PathToTempFolder);
		    filesForCopy = copier.FilesForCopy == null ? new DirectoryInfo(copier.SourceFolder).GetFiles(".", SearchOption.AllDirectories).ToList() : copier.FilesForCopy.Select(file => file.FileInfo).ToList();
		}

		/// <summary>
		/// Начать копирование в промежуточную папку.
		/// </summary>
		public void Start()
		{
            ChackFreeSpace();
            preCopier.Compute();
            copier.CountOfCopedFiles = preCopier.Files.Count();

		    if (copier.FilesForCopy != null)
		    {
		        ChackOnErrorWithHash();
		    }

            if (copier.InTempFolder != null)
            {
                copier.InTempFolder();
            }
		}

		private void ChackFreeSpace()
        {
			var size = Utils.DirSize(filesForCopy);
            if (size > tempDriverInfo.AvailableFreeSpace)
            {
                throw new SynchronizerException(tempDriverInfo, SynchronizerException.ErrorType.DriversOutOfMemory, size);
            }

            if (size > targetDriveInfo.AvailableFreeSpace)
            {
                throw new SynchronizerException(targetDriveInfo, SynchronizerException.ErrorType.DriversOutOfMemory, size);
            }
		}

		private void ChackOnErrorWithHash()
		{
		    var chacker = new HashChacker(copier.CheckSumFile, copier.SourceFolder, copier.PathToTempFolder,
		                                   copier.FilesForCopy);
			chacker.Check();
		}
	}
}
